package Gui;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import client.ConnectionClient;
import client.InformationHandler;
import datastructure.PatientRecord;

/**
 * The GUI pane where a user views and deletes patient records. It contains
 * one list of patient records. The user selects a patient record by clicking
 * in the list. The record data is shown in the fields in the right panel.
 * The bottom panel contains five buttons which the user can click to reload
 * the data, log out, delete a specific record, delete all records 
 * of a patient and search after all records to a patient.
 */
public class MedicalRecordPane extends BasicPane {
	private static final long serialVersionUID = 1;
	/**
	 * A label showing the name of the current user.
	 */
	private JLabel currentUserNameLabel;

	/**
	 * The list model for the patient record list.
	 */
	private DefaultListModel recordListModel;

	/**
	 * The patient record list.
	 */
	private JList nameList;

	/**
	 * The text fields where the patient record data is shown.
	 */
	private JTextField[] fields;

	/**
	 * The number of the record number field.
	 */
	private static final int RECORD_NBR = 0;

	/**
	 * The number of the SSN field.
	 */
	private static final int SSN = 1;

	/**
	 * The number of the nurse field.
	 */
	private static final int NURSE = 2;

	/**
	 * The number of the division field.
	 */
	private static final int DIVISION = 3;
	/**
	 * The number of the symptomes field.
	 */
	private static final int SYMPTOMES = 4;
	/**
	 * The number of the diagnosis field.
	 */
	private static final int DIAGNOSIS = 5;
	/**
	 * The number of the date field.
	 */
	private static final int DATE = 6;
	/**
	 * The number of the full name field.
	 */
	private static final int FULL_NAME = 7;

	/**
	 * The total number of fields.
	 */
	private static final int NBR_FIELDS = 8;

	/**
	 * The list where the patient records are stored.
	 */
	private ArrayList<PatientRecord> recordsList;

	/**
	 * The selected record.
	 */
	private PatientRecord selectedRecord;

	/**
	 * Create the medical record pane.
	 * 
	 * @param cc
	 *            The connection client object.
	 */
	public MedicalRecordPane(ConnectionClient cc) {
		super(cc);

	}

	/**
	 * Create the left panel, containing the patient record list.
	 * 
	 * @return The left panel.
	 */
	@Override
	public JComponent createLeftPanel() {
		recordListModel = new DefaultListModel();

		nameList = new JList(recordListModel);
		nameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		nameList.setPrototypeCellValue("123456789012");
		nameList.addListSelectionListener(new NameSelectionListener());
		nameList.setFixedCellWidth(200);
		JScrollPane p1 = new JScrollPane(nameList);
		JPanel p = new JPanel();
		p.setLayout(new GridLayout(1, 2));
		p.add(p1);
		return p;
	}

	/**
	 * Create the top panel, containing the fields with the patient record data.
	 * 
	 * @return The top panel.
	 */
	@Override
	public JComponent createTopPanel() {
		String[] texts = new String[NBR_FIELDS];
		texts[RECORD_NBR] = "Record number";
		texts[SSN] = "Social security number";
		texts[NURSE] = "Nurse";
		texts[DIVISION] = "Division";
		texts[SYMPTOMES] = "Symptomes";
		texts[DIAGNOSIS] = "Diagnosis";
		texts[DATE] = "Date";
		texts[FULL_NAME] = "Full name";

		fields = new JTextField[NBR_FIELDS];
		for (int i = 0; i < fields.length; i++) {
			fields[i] = new JTextField(20);
			fields[i].setEditable(false);
		}

		JPanel input = new InputPanel(texts, fields);

		JPanel p1 = new JPanel();
		p1.setLayout(new FlowLayout(FlowLayout.LEFT));
		p1.add(new JLabel("Current user: "));
		currentUserNameLabel = new JLabel("");
		p1.add(currentUserNameLabel);

		JPanel p = new JPanel();
		p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
		p.add(p1);
		p.add(input);
		return p;
	}

	/**
	 * Create the bottom panel, containing the buttons and the
	 * message line.
	 * 
	 * @return The bottom panel.
	 */
	@Override
	public JComponent createBottomPanel() {
		JButton[] buttons = new JButton[5];
		buttons[0] = new JButton("Log out");
		buttons[1] = new JButton("Delete");
		buttons[2] = new JButton("Delete All");
		buttons[3] = new JButton("Search");
		buttons[4] = new JButton("Reload");
		return new ButtonAndMessagePanel(buttons, messageLabel,
				new ActionHandler());
	}

	/**
	 * Perform the entry actions of this pane: clear all fields, fetch the patient
	 * records from the server and display them in the name list.
	 */
	@Override
	public void entryActions() {
		clearMessage();
		currentUserNameLabel.setText(CurrentUser.instance().getCurrentUserId());
		fillRecordList();
		clearFields();
	}

	/**
	 * Fetch patient records from the server and display them in the name
	 * list.
	 */
	private void fillRecordList() {
		if (CurrentUser.instance().isLoggedIn()) {
			recordListModel.removeAllElements();
			String data = CurrentUser.instance().toString() + ";read;padding";

			String in = cc.sendData(data);
			if (!in.equals("")) {
				recordsList = InformationHandler.parseToRecords(in);
				if (recordsList != null && recordsList.size() > 0) {
					for (int i = 0; i < recordsList.size(); i++) {
						recordListModel.addElement(recordsList.get(i)
								.getRecordNbr()
								+ ". " + recordsList.get(i).getSsn());
					}
				} else {
					displayMessage("There are no patient records to show!");
				}
			} else {
				displayMessage("There are no patient records to show!");
			}
		}
	}
	/**
	 * Only displays the patient records of the patient with social security number ssn.
	 * All other patient records are removed.
	 * @param ssn
	 * 			The social security number of the desired patient.
	 */
	private void fillRecordList(String ssn){
			PatientRecord p;
			ArrayList<PatientRecord> pa = new ArrayList<PatientRecord>();
			
			recordListModel.removeAllElements();
			
			for(int i = 0; i<recordsList.size(); i++){
				System.out.println(i);
				p = recordsList.get(i);
				
				if(p.getSsn().equalsIgnoreCase(ssn)){
					recordListModel.addElement(p.getRecordNbr() +". "+p.getSsn());
					pa.add(p);
				} 
			}
			recordsList = pa;
		}

	/**
	 * Clear all text fields.
	 */
	private void clearFields() {
		for (int i = 0; i < fields.length; i++) {
			fields[i].setText("");
		}
	}

	/**
	 * A class that listens for clicks in the name list.
	 */
	class NameSelectionListener implements ListSelectionListener {
		/**
		 * Called when the user selects a patient record in the name list. 
		 * Displays the record data in the text fields.
		 * 
		 * @param e
		 *            The selected list item.
		 */
		public void valueChanged(ListSelectionEvent e) {
			if (nameList.isSelectionEmpty()) {
				return;
			}
			int index = nameList.getSelectedIndex();
			selectedRecord = recordsList.get(index);

			if (selectedRecord != null) {
				fields[RECORD_NBR].setText(selectedRecord.getRecordNbr() + "");
				fields[SSN].setText(selectedRecord.getSsn());
				fields[NURSE].setText(selectedRecord.getNurse());
				fields[DIVISION].setText(selectedRecord.getDivision());
				fields[SYMPTOMES].setText(selectedRecord.getSymptomes());
				fields[DIAGNOSIS].setText(selectedRecord.getDiagnos());
				fields[DATE].setText(selectedRecord.getDate());
				fields[FULL_NAME].setText(selectedRecord.getFullName());
			}
		}
	}

	/**
	 * A class that listens for button clicks.
	 */
	class ActionHandler implements ActionListener {
		/**
		 * Called when the user clicks a button. 
		 * 
		 * @param e
		 *            The event object.
		 */
		public void actionPerformed(ActionEvent e) {
			JButton provoker = (JButton) e.getSource();
			if (CurrentUser.instance().isLoggedIn()) {
				if (provoker.getLabel().equalsIgnoreCase("Log out")) {
					System.out.println("Log out");
					CurrentUser.instance().loginAs(null, null);
					currentUserNameLabel.setText("");
					recordsList.clear();
					selectedRecord = null;
					clearFields();
					recordListModel.clear();

				} else if (provoker.getLabel().equalsIgnoreCase("Delete")) {
					System.out.println("Delete");
					if (selectedRecord != null) {
						String ans = JOptionPane
								.showInputDialog("Are you sure?(y/N)");
						if (ans != null) {
							if (ans.equalsIgnoreCase("y")) {
								String output = CurrentUser.instance()
										.toString()
										+ ";delete;"
										+ selectedRecord.getRecordNbr();
								String response = cc.sendData(output);
								if (response.equalsIgnoreCase("ACK")) {
									displayMessage("The record with record number "
											+ selectedRecord.getRecordNbr()
											+ " was deleted");
									selectedRecord = null;
									fillRecordList();
								} else {
									displayMessage("Unable to delete record with record number "
											+ selectedRecord.getRecordNbr());
								}
							}
						}
					} else {
						displayMessage("Please select the record to be deleted and click again");
					}
				} else if (provoker.getLabel().equalsIgnoreCase("Delete All")) {
					System.out.println("Delete All");
					String ssn = JOptionPane
							.showInputDialog("Enter the social security which belongs to the records.");

					if (ssn != null && !ssn.equals("")) {
						String ans = JOptionPane
								.showInputDialog("Are you sure?(y/N)");
						if (ans.equalsIgnoreCase("y")) {
							String output = CurrentUser.instance().toString()
									+ ";deleteall;" + ssn;
							String response = cc.sendData(output);
							if (response.equalsIgnoreCase("ACK")) {
								displayMessage("All records with social security number "
										+ ssn + " was deleted");
								fillRecordList();
							} else {
								displayMessage("Unable to delete records with social security number "
										+ ssn);
							}

						}
					}
				} else if (provoker.getLabel().equalsIgnoreCase("Search")) {
					System.out.println("Search");
					String ssn = JOptionPane.showInputDialog("Enter the patient SSN: ");
					if (ssn != null && !ssn.equals("")) {
						fillRecordList(ssn);	
					}
				} else if(provoker.getLabel().equalsIgnoreCase("Reload")){
					fillRecordList();
				}
			} else {
				displayMessage("You must log in first!");
			}
		}
	}
}
